import input.JOGRInputHandler;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.ImageIcon;

import jmetest.flagrushtut.lesson5.Lesson5;

import com.jme.app.FixedFramerateGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.AbsoluteMouse;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.GameSettings;
import com.jme.system.JmeException;
import com.jme.system.PropertiesGameSettings;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.util.states.PhysicsGameState;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;


/*
 * Hi Greg! This is just a note to test and see if Eclipse works with SVN now!
 */

public class JOGRGame extends FixedFramerateGame{
		private Timer timer;
		private Camera cam;
		private int width, height, depth, freq;
		private boolean fullscreen;
		private PhysicsGameState physGameState;
		private JOGRInputHandler input;
		private AbsoluteMouse mouse;
		
		private static final Logger logger = Logger.getLogger(Lesson5.class.getName());
		
		//Root node of the scene graph
		private Node scene;
	
	public static void main(String[] args) {
		JOGRGame game = new JOGRGame();
		game.setConfigShowMode(ConfigShowMode.AlwaysShow);
		game.start();

	}

	protected void initGame() {
		display.setTitle("This is an attempt at a change!");
		scene = new Node("Scene Graph Node");
		initRenderStates();
		initMouse();
		createTerrain();
		
		scene.updateGeometricState(0.0f, true);
		scene.updateRenderState();
		

	}

	@Override
	protected void initSystem() {
		//Store the settings information
		width = settings.getWidth();
		height = settings.getHeight();
		depth = settings.getDepth();
		freq = settings.getFrequency();
		fullscreen = settings.isFullscreen();
		
		try {
			display = DisplaySystem.getDisplaySystem(settings.getRenderer());
			display.createWindow(width, height, depth, freq, fullscreen);
			
			cam = display.getRenderer().createCamera(width, height);
		}
		catch (JmeException e){
			logger.log(Level.SEVERE, "Could not create display system", e);
			System.exit(1);		
		}
		
		physGameState = new PhysicsGameState("physGameState");
		//Change default camera here
		cam.setFrustumPerspective(45.0f, (float)width / (float) height, 1, 1000);
		Vector3f loc = new Vector3f(250.0f, 50f, 250.0f);
		Vector3f left = new Vector3f(-0.5f, 0.0f, 0.5f);
		Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
		Vector3f dir = new Vector3f(-0.5f, -0.1f, -0.5f);
		cam.setFrame(loc, left, up, dir);
		cam.update();
		display.getRenderer().setCamera(cam);
				
		input = new JOGRInputHandler(cam, settings.getRenderer());
		
		
		timer = Timer.getTimer();		
		display.getRenderer().setBackgroundColor(ColorRGBA.black);
		
        KeyBindingManager.getKeyBindingManager().set("exit",
                KeyInput.KEY_ESCAPE);
	}


	protected void reinit() {
		display.recreateWindow(width, height, depth, freq, fullscreen);
	}

	
	protected void render(float interpolation) {
		display.getRenderer().clearBuffers();
		display.getRenderer().draw(scene);		
	}

	protected void update(float interpolation) {
		timer.update();
		interpolation = timer.getTimePerFrame();
		input.update(interpolation);
		
	}
	
	/*
	 * (non-Javadoc) Cleanup textures, this is done automatically anyway?
	 * @see com.jme.app.FixedFramerateGame#cleanup()
	 */
	protected void cleanup() {

	}

	private void initRenderStates() {
		//Use a zbuffer, so pixels further away are not drawn.
		ZBufferState zBuf = display.getRenderer().createZBufferState();
		zBuf.setEnabled(true);
		zBuf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
		scene.setRenderState(zBuf);
		
		//Cull back facing triangles
		CullState cs = display.getRenderer().createCullState();
		cs.setCullFace(CullState.Face.Back);
		scene.setRenderState(cs);
	}
	
	private void initMouse() {
		mouse =  new AbsoluteMouse("cursor",  width, height);
		TextureState cursorTS = util.util.createTextureState("jmetest/data/cursor/cursor1.png");
		mouse.setRenderState(cursorTS);
		
		//The blend state removes the white box around the mouse.
        BlendState mouseBlendState = display.getRenderer().createBlendState();
        mouseBlendState.setBlendEnabled(true);
        mouseBlendState.setSourceFunction(BlendState.SourceFunction.One);
        mouseBlendState.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceColor);
        mouseBlendState.setTestEnabled(true);
        mouseBlendState.setTestFunction(BlendState.TestFunction.GreaterThan);
        mouse.setRenderState(mouseBlendState);
        mouse.registerWithInputHandler(input);
		scene.attachChild(mouse);
	}

	private void createTerrain() {
		StaticPhysicsNode floorNode = physGameState.getPhysicsSpace().createStaticNode();
		scene.attachChild(floorNode);

		
		MidPointHeightMap terrainHeightMap = new MidPointHeightMap(64, 1f);
		Vector3f terrainScale = new Vector3f(4,0.3f,4);
		
		TerrainBlock terrainBlock = new TerrainBlock("Terrain", terrainHeightMap.getSize(),
				terrainScale, terrainHeightMap.getHeightMap(), new Vector3f());
		terrainBlock.setModelBound(new BoundingBox());
		terrainBlock.updateModelBound();

		//Create a texture based on height
		ProceduralTextureGenerator terrainTexGen = new ProceduralTextureGenerator(terrainHeightMap);
		terrainTexGen.addTexture(new ImageIcon(JOGRGame.class.getClassLoader().
				getResource("jmetest/data/texture/grassb.png")), -128, 0, 128);
		terrainTexGen.addTexture(new ImageIcon(JOGRGame.class.getClassLoader().
				getResource("jmetest/data/texture/dirt.jpg")), 96, 160, 224);
		terrainTexGen.addTexture(new ImageIcon(JOGRGame.class.getClassLoader().
				getResource("jmetest/data/texture/highest.jpg")), 192, 256, 320);
		terrainTexGen.createTexture(512);
		
		Texture terrainTex = TextureManager.loadTexture(terrainTexGen.getImageIcon().getImage(),
				Texture.MinificationFilter.BilinearNearestMipMap,
				Texture.MagnificationFilter.Bilinear,
				true);		
		
		TextureState ts = display.getRenderer().createTextureState();
		ts.setTexture(terrainTex);
		terrainBlock.setRenderState(ts);

		floorNode.attachChild(terrainBlock);
		floorNode.generatePhysicsGeometry();
	}

	
	protected GameSettings getNewSettings() {
		return new JOGRGameSettings();
	}
	
	static class JOGRGameSettings extends PropertiesGameSettings{
		static {
			//Override defaul settings here.
			defaultFullscreen = Boolean.FALSE;
		}	
		public JOGRGameSettings() {
			super("properties.cfg");
			load();
			// TODO Auto-generated constructor stub
		}
	}


}
